//
//  SSDKPluginHttpUtil.m
//  SSDKPlugin-demo
//
//  Created by 涂俊 on 2017/7/5.
//  Copyright © 2017年 涂俊. All rights reserved.
//

#import "SSDKPluginHttpUtil.h"
#import "SSDKPluginStringUtil.h"
#import "SSDKPluginJsonUtil.h"
#import "SSDKPluginReachability.h"

@implementation SSDKPluginHttpUtil

static int const TIME_OUT = 8;


+ (void)postWithUrl : (NSString *)url
               data : (NSDictionary *)data
            delegate:(void (^)(BOOL networkAvaliable, NSInteger status, NSString* resData))delegate {
    [self postWithUrl:url data:data delegate:delegate retry:0];
}

+ (void)postWithUrl : (NSString *)url
               data : (NSDictionary *)data
            delegate:(void (^)(BOOL networkAvaliable, NSInteger status, NSString* resData))delegate
               retry:(int) retryTimes {
    NSString *dataStr = [SSDKPluginStringUtil stringFromParams:data];
    NSLog(@"httpPost,url=%@,data=%@", url, dataStr);
    //检查网络情况
    if (![self isNetworkReachable]) {
        delegate(NO, NSIntegerMin, nil);
        return;
    }
    NSData *postData = [dataStr dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
    NSString *postLength = [NSString stringWithFormat:@"%lu", (unsigned long)[postData length]];
    NSURL *nsUrl = [[NSURL alloc] initWithString:url];
    
    NSMutableURLRequest *request = [NSMutableURLRequest
                                    requestWithURL : nsUrl
                                    cachePolicy:NSURLRequestReloadIgnoringCacheData
                                    timeoutInterval:TIME_OUT];
    request.HTTPMethod = @"POST";
    [request setValue:postLength forHTTPHeaderField:@"Content-Length"];
    [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
    [request setValue:@"close" forHTTPHeaderField:@"Connection"];
    request.HTTPBody = postData;
    // 重试逻辑先忽略
    //    [[SSDKPluginHttpUtil getInstance] addRequestRecord:request];
    
    [self dealWithRequest:request delegate:delegate retry:retryTimes];
}


+ (void)postJsonWithUrl : (NSString *)url
                   data : (NSDictionary *)data
                delegate:(void (^)(BOOL networkAvaliable, NSInteger status, NSString* resData))delegate {
    [self postJsonWithUrl:url data:data delegate:delegate retry:0];
}

+ (void)postJsonWithUrl : (NSString *)url
                   data : (NSDictionary *)data
                delegate:(void (^)(BOOL networkAvaliable, NSInteger status, NSString* resData))delegate
                   retry:(int) retryTimes {
    NSString *dataStr = [SSDKPluginJsonUtil toJsonWithObject:data];
    NSLog(@"httpPostJson,url=%@,data=%@", url, dataStr);
    //检查网络情况
    if (![self isNetworkReachable]) {
        delegate(NO, NSIntegerMin, nil);
        return;
    }
    NSData *postData = [dataStr dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
    NSString *postLength = [NSString stringWithFormat:@"%lu", (unsigned long)[postData length]];
    NSURL *nsUrl = [[NSURL alloc] initWithString:url];
    
    NSMutableURLRequest *request = [NSMutableURLRequest
                                    requestWithURL : nsUrl
                                    cachePolicy:NSURLRequestReloadIgnoringCacheData
                                    timeoutInterval:TIME_OUT];
    request.HTTPMethod = @"POST";
    [request setValue:postLength forHTTPHeaderField:@"Content-Length"];
    [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    [request setValue:@"close" forHTTPHeaderField:@"Connection"];
    request.HTTPBody = postData;
    // 重试逻辑先忽略
    //    [[SSDKPluginHttpUtil getInstance] addRequestRecord:request];
    
    [self dealWithRequest:request delegate:delegate retry:retryTimes];
}


+ (void)getWithUrl:(NSString *)url
              data:(NSDictionary *)data
          delegate:(void (^)(BOOL networkAvaliable, NSInteger status, NSString* resData))delegate {
    [self getWithUrl:url data:data delegate:delegate retry:0];
}

+ (void)getWithUrl:(NSString *)url
              data:(NSDictionary *)data
          delegate:(void (^)(BOOL networkAvaliable, NSInteger status, NSString* resData))delegate
             retry:(int) retryTimes {
    NSString *dataStr = [SSDKPluginStringUtil stringFromParams:data];
    NSLog(@"httpPost,url=%@,data=%@", url, dataStr);
    //检查网络情况
    if (![self isNetworkReachable]) {
        delegate(NO, NSIntegerMin, nil);
        return;
    }
    
    NSString *URLFellowString = (data != nil ? [@"?"stringByAppendingString:dataStr] : @"");
    NSURL *nsUrl = [[NSURL alloc] initWithString:[url stringByAppendingString:URLFellowString]];
    NSMutableURLRequest *request = [NSMutableURLRequest
                                    requestWithURL : nsUrl
                                    cachePolicy:NSURLRequestReloadIgnoringCacheData
                                    timeoutInterval:TIME_OUT];
    request.HTTPMethod = @"GET";
    [request setValue:@"close" forHTTPHeaderField:@"Connection"];
    // 重试逻辑先忽略
    //    [[OpenSDK_HttpUtil getInstance] addRequestRecord:request];
    
    [self dealWithRequest:request delegate:delegate retry:retryTimes];
}


+ (void)delWithUrl:(NSString *)url
              data:(NSDictionary *)data
          delegate:(void (^)(BOOL networkAvaliable, NSInteger status, NSString* resData))delegate {
    [self delWithUrl:url data:data delegate:delegate retry:0];
}

//delete方法
+ (void)delWithUrl:(NSString *)url
              data:(NSDictionary *)data
          delegate:(void (^)(BOOL networkAvaliable, NSInteger status, NSString* resData))delegate
             retry:(int) retryTimes {
    NSString *dataStr = [SSDKPluginStringUtil stringFromParams:data];
    NSLog(@"httpPost,url=%@,data=%@", url, dataStr);
    //检查网络情况
    if (![self isNetworkReachable]) {
        delegate(NO, NSIntegerMin, nil);
        return;
    }
    NSString *URLFellowString = [@"?" stringByAppendingString:dataStr];
    NSURL *nsUrl = [[NSURL alloc] initWithString:[url stringByAppendingString:URLFellowString]];
    NSMutableURLRequest *request = [NSMutableURLRequest
                                    requestWithURL : nsUrl
                                    cachePolicy:NSURLRequestReloadIgnoringCacheData
                                    timeoutInterval:TIME_OUT];
    
    request.HTTPMethod = @"DELETE";
    [request setValue:@"close" forHTTPHeaderField:@"Connection"];
    [request setHTTPBody:[dataStr dataUsingEncoding:NSUTF8StringEncoding]];
    // 重试逻辑先忽略
    //    [[OpenSDK_HttpUtil getInstance] addRequestRecord:request];
    
    [self dealWithRequest:request delegate:delegate retry:retryTimes];
}



+ (void)postUIWithUrl:(NSString *)url
                 data:(NSDictionary *)data
             delegate:(void (^)(BOOL networkAvaliable, NSInteger status, NSString* resData))delegate {
    [self postWithUrl:url data:data delegate:^(BOOL networkAvaliable, NSInteger status, NSString *resData) {
        //使用UI线程回调
        dispatch_async(dispatch_get_main_queue(), ^{
            delegate(networkAvaliable, status, resData);
        });
    }];
}

+ (void)postJsonUIWithUrl:(NSString *)url
                     data:(NSDictionary *)data
                 delegate:(void (^)(BOOL networkAvaliable, NSInteger status, NSString* resData))delegate {
    [self postJsonWithUrl:url data:data delegate:^(BOOL networkAvaliable, NSInteger status, NSString *resData) {
        //使用UI线程回调
        dispatch_async(dispatch_get_main_queue(), ^{
            delegate(networkAvaliable, status, resData);
        });
    }];
}

+ (void)getUIWithUrl:(NSString *)url
                data:(NSDictionary *)data
            delegate:(void (^)(BOOL networkAvaliable, NSInteger status, NSString* resData))delegate {
    [self getWithUrl:url data:data delegate:^(BOOL networkAvaliable, NSInteger status, NSString *resData) {
        //使用UI线程回调
        dispatch_async(dispatch_get_main_queue(), ^{
            delegate(networkAvaliable, status, resData);
        });
    }];
}

+ (void)delUIWithUrl:(NSString *)url
                data:(NSDictionary *)data
            delegate:(void (^)(BOOL networkAvaliable, NSInteger status, NSString* resData))delegate {
    [self delWithUrl:url data:data delegate:^(BOOL networkAvaliable, NSInteger status, NSString *resData) {
        //使用UI线程回调
        dispatch_async(dispatch_get_main_queue(), ^{
            delegate(networkAvaliable, status, resData);
        });
    }];
}


+ (void)dealWithRequest:(NSMutableURLRequest *)request
               delegate:(void (^)(BOOL networkAvaliable, NSInteger status, NSString* resData))delegate
                  retry:(int) retryTimes {
    NSOperationQueue *queue = [NSOperationQueue new];
    [NSURLConnection sendAsynchronousRequest:request queue:queue
                           completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
                               //将data解析为字符串
                               NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
                               NSInteger status = [httpResponse statusCode];
                               NSString *dataStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
                               if (retryTimes > 0 && (status < 200 || status >= 300)) {
                                   //返回码非2xx，且可重试次数大于0，则进行重试
                                   NSLog(@"Http retry!,url=%@", request.URL.absoluteString);
                                   [self dealWithRequest:request delegate:delegate retry:(retryTimes - 1)];
                               } else {
                                   //直接在本线程回调
                                   delegate(YES, status, dataStr);
                               }
                           }];
}

+ (BOOL)isNetworkReachable {
    BOOL isReachable = NO;
    SSDKPluginReachability *reachability = [SSDKPluginReachability reachabilityWithHostName:@"ssdk.sail2world.com"];
    switch ([reachability currentReachabilityStatus]) {
        case NotReachable:
            isReachable = NO;
            break;
        default:
            isReachable = YES;
            break;
    }
    return isReachable;
}

@end
